package com.bridata.service.impl;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.bridata.mapper.ScreenPictureMapper;
import com.bridata.model.entity.ScreenPicture;
import com.bridata.service.ScreenPictureService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 屏幕图片服务实现类
 */
@Slf4j
@Service
public class ScreenPictureServiceImpl implements ScreenPictureService {

    private static final int MAX_RETRIES = 3;
    private static final int HTTP_TIMEOUT = 5000; // 5秒

    // 性能监控指标
    private static final AtomicLong successCount = new AtomicLong(0);
    private static final AtomicLong failureCount = new AtomicLong(0);

    @Autowired
    private ScreenPictureMapper screenPictureMapper;

    @Value("${api.url2image.base-url:http://10.120.79.139:3000/api/url2image}")
    private String baseUrl;

    @Value("${api.template.base-url:http://10.128.103.90:8098/t2fids-web-boss/template/templates/view.do}")
    private String templateBaseUrl;

    private final ExecutorService processExecutor = Executors.newFixedThreadPool(
            Runtime.getRuntime().availableProcessors() * 2
    );

    @Override
    public List<ScreenPicture> fetchRecords(int offset, int size) {
        return screenPictureMapper.fetchRecords(offset, size);
    }

    @Override
    @Async
    public void processSingleRecord(ScreenPicture record) {
        try {
            if (StringUtils.isEmpty(record.getTemplate_id())) {
                return;
            }
            String imageData = fetchImageWithRetry(record);
            updateDatabaseRecord(record, imageData);
            successCount.incrementAndGet();
        } catch (Exception e) {
            failureCount.incrementAndGet();
            log.error("记录处理失败 ID: {}", record.getId(), e);
        }
    }

    @Override
    public void processRecordsAsync(List<ScreenPicture> records) {
        List<CompletableFuture<Void>> futures = new ArrayList<>();
        for (ScreenPicture record : records) {
            futures.add(CompletableFuture.runAsync(() -> {
                processSingleRecord(record);
            }, processExecutor));
        }
        try {
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get(30, TimeUnit.SECONDS);
        } catch (Exception e) {
            log.error("批量任务执行异常", e);
        }
    }

    @Override
    public void updateDatabaseRecord(ScreenPicture record, String imageData) {
        try {
            int affectedRows = screenPictureMapper.updatePicture(record.getId(), imageData);
            if (affectedRows == 0) {
                log.warn("未更新任何记录 ID: {}", record.getId());
            }
        } catch (Exception e) {
            log.error("数据库更新失败", e);
            throw new RuntimeException("数据库更新失败", e);
        }
    }

    @Override
    public String fetchImageData(ScreenPicture item) {
        log.info("当前请求数据id: {}", item.getTemplate_id());
        String picUrl = String.format("%s?id=%s", templateBaseUrl, item.getTemplate_id());
        
        JSONObject requestBody = new JSONObject();
        requestBody.put("url", picUrl);
        requestBody.put("width", "1920");
        requestBody.put("height", "1080");
        requestBody.put("fullPage", false);
        requestBody.put("autoSize", false);
        requestBody.put("imageFormat", "jpeg");
        requestBody.put("imageQuality", "60");
        
        HttpResponse response = HttpRequest
                .post(baseUrl)
                .body(requestBody.toJSONString())
                .timeout(HTTP_TIMEOUT)
                .execute();
        
        if (response.getStatus() != 200) {
            log.error("HTTP请求失败，状态码: {}", response.getStatus());
        }
        
        JSONObject responseJson = JSONObject.parseObject(response.body());
        return responseJson.getString("imageBase64WithPrefix");
    }

    @Override
    public String fetchImageWithRetry(ScreenPicture record) {
        for (int retry = 0; retry < MAX_RETRIES; retry++) {
            try {
                return fetchImageData(record);
            } catch (Exception e) {
                if (retry == MAX_RETRIES - 1) {
                    log.error("API请求失败，已达最大重试次数", e);
                    throw new RuntimeException("API请求失败", e);
                }
                sleepExponentialBackoff(retry);
            }
        }
        return "";
    }

    private void sleepExponentialBackoff(int retryCount) {
        try {
            Thread.sleep(1000L * (1 << retryCount));
        } catch (InterruptedException ie) {
            Thread.currentThread().interrupt();
        }
    }

    public AtomicLong getSuccessCount() {
        return successCount;
    }

    public AtomicLong getFailureCount() {
        return failureCount;
    }
}